import 'package:string_scanner/string_scanner.dart';

import '../common/test_page.dart';

class ErrorTestPage extends TestPage {
  ErrorTestPage(super.title) {
    test('默认为最后一个匹配', () {
      final scanner = StringScanner('foo bar baz');
      scanner.expect('foo ');
      scanner.expect('bar');
      scanner.error('oh no!');
    });

    group('with match', () {
      test('支持较早的匹配', () {
        final scanner = StringScanner('foo bar baz');
        scanner.expect('foo ');
        final match = scanner.lastMatch;
        scanner.expect('bar');
        scanner.error('oh no!', match: match);
      });

      test('支持前一行的匹配', () {
        final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water');
        scanner.expect('foo bar baz\ndo ');
        scanner.expect('re');
        final match = scanner.lastMatch;
        scanner.expect(' mi\nearth ');
        scanner.error('oh no!', match: match);
      });

      test('支持多行匹配', () {
        final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water');
        scanner.expect('foo bar ');
        scanner.expect('baz\ndo');
        final match = scanner.lastMatch;
        scanner.expect(' re mi');
        scanner.error('oh no!', match: match);
      });

      test('支持位置后的比赛', () {
        final scanner = StringScanner('foo bar baz');
        scanner.expect('foo ');
        scanner.expect('bar');
        final match = scanner.lastMatch;
        scanner.position = 0;
        scanner.error('oh no!', match: match);
      });
    });

    group('with position and/or length', () {
      test('默认长度为0', () {
        final scanner = StringScanner('foo bar baz');
        scanner.expect('foo ');
        scanner.error('oh no!', position: 1);
      });

      test('默认为当前位置', () {
        final scanner = StringScanner('foo bar baz');
        scanner.expect('foo ');
        scanner.error('oh no!', length: 3);
      });

      test('支持早期位置', () {
        final scanner = StringScanner('foo bar baz');
        scanner.expect('foo ');
        scanner.error('oh no!', position: 1, length: 2);
      });

      test('支持前一行上的位置', () {
        final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water');
        scanner.expect('foo bar baz\ndo re mi\nearth');
        scanner.error('oh no!', position: 15, length: 2);
      });

      test('支持多行长度', () {
        final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water');
        scanner.expect('foo bar baz\ndo re mi\nearth');
        scanner.error('oh no!', position: 8, length: 8);
      });

      test('支持当前位置之后的位置', () {
        final scanner = StringScanner('foo bar baz');
        scanner.error('oh no!', position: 4, length: 3);
      });

      test('支持长度为零', () {
        final scanner = StringScanner('foo bar baz');
        scanner.error('oh no!', position: 4, length: 0);
      });
    });

    group('argument errors', () {

      test('如果匹配通过了位置', () {
        StringScanner scanner = StringScanner('foo bar baz');
        scanner.scan('foo');
        scanner.error('oh no!', match: scanner.lastMatch, position: 1);
      });

      test('如果匹配通过长度', () {
        StringScanner scanner = StringScanner('foo bar baz');
        scanner.scan('foo');
        scanner.error('oh no!', match: scanner.lastMatch, length: 1);
      });

      test('如果位置为负数', () {
        StringScanner scanner = StringScanner('foo bar baz');
        scanner.scan('foo');
        scanner.error('oh no!', position: -1);
      });

      test('如果位置在字符串之外', () {
        StringScanner scanner = StringScanner('foo bar baz');
        scanner.scan('foo');
        scanner.error('oh no!', position: 100);
      });

      test('如果位置+长度在字符串之外', () {
        StringScanner scanner = StringScanner('foo bar baz');
        scanner.scan('foo');
        scanner.error('oh no!', position: 7, length: 7);
      });

      test('如果长度为负数', () {
        StringScanner scanner = StringScanner('foo bar baz');
        scanner.scan('foo');
        scanner.error('oh no!', length: -1);
      });
    });
  }

}